<?php
declare(strict_types=1);

namespace app\openapi\controller;

use think\Request;
use think\Db;

class Chat extends Base
{
    // OpenAI API配置
    private $openaiApiKey;
    private $openaiBaseUrl = 'https://wanqing.streamlakeapi.com/api/gateway/v1/endpoints';
    
    public function __construct()
    {
        parent::__construct();

        // 从配置文件或环境变量获取API Key
        if (request()->path() == 'api/gateway/v1/endpoints/batch/chat/completions') {
            $this->openaiBaseUrl = 'https://wanqing.streamlakeapi.com/api/gateway/v1/endpoints/batch';    
        }else{
            $this->openaiBaseUrl = 'https://wanqing.streamlakeapi.com/api/gateway/v1/endpoints';
        }
        
        $this->openaiApiKey = config('config.openapi.sk');
    }
    
    /**
     * Chat Completions接口转发
     * 支持流式和非流式调用
     */
    public function completions(Request $request)
    {
        try {
            // 获取请求参数
            $requestData = $request->getContent();
            $headers = $this->getForwardHeaders($request);
            
            // 解析请求数据判断是否为流式调用
            $data = json_decode($requestData, true);
            $isStream = isset($data['stream']) && $data['stream'] === true;
            
            if ($isStream) {
                $this->handleStreamRequest($requestData, $headers);
                return; // 流式响应不需要返回值
            } else {
                return $this->handleNormalRequest($requestData, $headers);
            }
            
        } catch (\Exception $e) {
            // Log::error('OpenAI API转发错误: ' . $e->getMessage());
            return json([
                'error' => [
                    'message' => $e->getMessage(),
                    'type' => 'api_error'
                ]
            ], 500);
        }
    }
    
    /**
     * 处理非流式请求
     */
    private function handleNormalRequest(string $requestData, array $headers)
    {
        $response = httpRequest($this->openaiBaseUrl . '/chat/completions',$requestData,'POST',$headers);

        // 记录完整的请求和响应信息
        if (!empty($response)) {
            $this->logApiCall($requestData, $response, $headers, 'normal');
        }
        
        return $response;
    }
    
    /**
     * 处理流式请求
     */
    private function handleStreamRequest(string $requestData, array $headers): void
    {
        // 设置流式响应头
        header('Content-Type: text/event-stream');
        header('Cache-Control: no-cache');
        header('Connection: keep-alive');
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: POST, OPTIONS');
        header('Access-Control-Allow-Headers: Content-Type, Authorization');
        
        // 立即输出头部
        ob_end_flush();
        
        $this->streamResponse($requestData, $headers);
    }
    
    /**
     * 流式响应处理
     */
    private function streamResponse(string $requestData, array $headers): void
    {
        $ch = curl_init();
        $streamBuffer = '';
        $dataBuffer = '';
        $streamResponses = [];
        $totalTokens = 0;

        curl_setopt_array($ch, [
            CURLOPT_URL => $this->openaiBaseUrl . '/chat/completions',
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $requestData,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_WRITEFUNCTION => function($ch, $data) use (&$streamBuffer,&$dataBuffer, &$streamResponses, &$totalTokens) {
                echo $data;
                ob_flush();
                flush();

                // 缓存完整流式数据
                $streamBuffer .= $data;
                // 解析流式数据
                $lines = explode("\n", $streamBuffer);
                $streamBuffer = array_pop($lines);

                $streamResponses[] = $data;

                foreach ($lines as $line) {
                    if ($line == "") {
                        $dataBuffer = substr($dataBuffer,5);
                        if ($dataBuffer !== '[DONE]' && !empty($dataBuffer) && !empty(trim($dataBuffer))) {
                            $decoded = json_decode($dataBuffer, true);
                            if ($decoded) {
                                // $streamResponses[] = $decoded;
                                // 获取token信息
                                if (isset($decoded['usage']['total_tokens'])) {
                                    $totalTokens = $decoded['usage']['total_tokens'];
                                }
                            }
                        }
                        $dataBuffer = "";
                    }else{
                        $dataBuffer .= trim($line);
                    }
                }
                
                
                return strlen($data);
            },
            CURLOPT_TIMEOUT => 0,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
        ]);
        
        curl_exec($ch);
        
        if (curl_error($ch)) {
            $error = curl_error($ch);
            echo "data:" . json_encode(['error' => $error]) . "\n\n";
            ob_flush();
            flush();
        } else {
            // 流式调用完成后记录完整信息
            $this->logApiCall($requestData, $streamResponses , $headers, 'stream', $totalTokens);
        }
        
        curl_close($ch);
    }
    
    /**
     * 获取转发请求头
     */
    private function getForwardHeaders(Request $request): array
    {
        $headers = [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $this->openaiApiKey,
        ];
        
        // 转发用户代理
        // if ($request->header('User-Agent')) {
        //     $headers[] = 'User-Agent: ' . $request->header('User-Agent');
        // }
        
        // // 转发其他相关头部
        // $forwardHeaders = ['Accept', 'Accept-Encoding', 'Accept-Language'];
        // foreach ($forwardHeaders as $headerName) {
        //     $headerValue = $request->header($headerName);
        //     if ($headerValue) {
        //         $headers[] = $headerName . ': ' . $headerValue;
        //     }
        // }
        
        return $headers;
    }
    
    /**
     * 处理OPTIONS预检请求
     */
    public function options()
    {
        return response('', 200, [
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Methods' => 'POST, OPTIONS',
            'Access-Control-Allow-Headers' => 'Content-Type, Authorization',
            'Access-Control-Max-Age' => '86400'
        ]);
    }
    
    /**
     * 记录API调用信息
     */
    private function logApiCall($requestData, $responseData, $headers, string $type, int $tokens = 0): void
    {
        try {
            // 处理响应数据
            if ($type === 'normal') {
                $response = is_string($responseData) ? json_decode($responseData, true) : $responseData;
                $tokens = $response['usage']['total_tokens'] ?? 0;
            } else {
                // 流式响应已经是数组格式
                $response = $responseData;
            }
            // dump(json_encode($response, JSON_UNESCAPED_UNICODE));die;

            // 插入数据库记录
            $ulogin = $this->login_user;
            Db::name('streamlake_record')->insert([
                'user_id'=>$ulogin['user_id'],
                'utype'=>$ulogin['utype'],
                'ram_id'=>$ulogin['ram_id'],
                'tokens' => $tokens,
                'params' => $requestData,
                'api_url'=>$this->openaiBaseUrl . '/chat/completions',
                'api_header'=>json_encode($headers, JSON_UNESCAPED_UNICODE),
                'api_result' => json_encode($response, JSON_UNESCAPED_UNICODE),
                'type' => $type,
                'ctime' => time()
            ]);
            // 扣除用户额度
            Db::name('user')->where('id',$ulogin['user_id'])->dec('streamlake_balance',$tokens)->update();
        } catch (\Exception $e) {
            
        }
    }
}